import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
import math
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from mpl_toolkits.mplot3d import Axes3D 
from matplotlib import cm

def gaussian(deviation):
    gaussian_y = []
    i = np.arange(0.0,1.0,0.01)
    for x in i:
        z = (x-mean_x)/deviation
        gaussian_y.append(kernel(z))    
    return i, gaussian_y

def kernel(z):
    return math.exp(-(z*z)/2)/math.sqrt(2*math.pi)

plt.figure(figsize=(8,4))

CENTERS = 4
X,y = make_blobs(n_samples=200,n_features=2,centers=CENTERS,
                 random_state=8, cluster_std=1)
y = y % 2
scaler = MinMaxScaler()
scaler.fit(X)
X = scaler.transform(X)

for target in range(CENTERS):
    plt.scatter(X[y==target,1], X[y==target,0], marker='^', 
                label='class '+format(target))    

mean_x = np.mean(X[:,1])
DEVIATION = 0.2  
x, gaussian_y = gaussian(DEVIATION)
plt.scatter(x, gaussian_y, marker='.', color='green') 
x, gaussian_y = gaussian(DEVIATION*0.3)
plt.scatter(x, gaussian_y, marker='.', color='cyan')

gaussian_z = [[],[]]
for i in range(len(y)):
    z = (X[:,1][i]-mean_x)/DEVIATION 
    gaussian_z[y[i]].append(kernel(z)*X[:,1][i])         
        
X_h = np.arange(int(min(X[:,0])), int(max(X[:,0])), 0.005)
Y_h = np.arange(int(min(X[:,1])), int(max(X[:,1])), 0.005)
X_h, Y_h = np.meshgrid(X_h, Y_h)
Z = -(-0.1*Y_h+0.02*X_h-0.04)/1  # Arbitrary values for this example

fig = plt.figure(figsize=(8, 4))
ax = Axes3D(fig, elev=30, azim=-30)

for target in range(2):    
    ax.scatter(X[y==target,1], X[y==target,0], gaussian_z[target],
               marker='^')   # Plot the features
# Plot the plane surface.
ax.plot_surface(Y_h, X_h, Z, cmap=cm.coolwarm)     
   
plt.show()
